﻿#pragma once

#include <stdexcept>
#include <string>

namespace kratos {
namespace service {

#define DECLARE_SYSTEM_EXCEPTION(name)                                         \
  class name : public SystemException {                                        \
  public:                                                                      \
    explicit name(const char *reason) noexcept : SystemException(reason) {}    \
    virtual ~name() {}                                                         \
  };

/**
 * 由底层抛出的不能使用try-catch捕获的系统软件/硬件异常，转换为SystemException.
 */
class SystemException : public std::exception {
  std::string reason_;

public:
  explicit SystemException(const char *reason) noexcept { reason_ = reason; }
  virtual ~SystemException() {}
  virtual const char *what() const noexcept { return reason_.c_str(); }
};
/**
 * 内存访问违规.
 */
DECLARE_SYSTEM_EXCEPTION(SegmentationFaultException)
/**
 * 除零错误.
 */
DECLARE_SYSTEM_EXCEPTION(NumberException)
/**
 * 数组错误.
 */
DECLARE_SYSTEM_EXCEPTION(ArrayException)
/**
 * 栈错误.
 */
DECLARE_SYSTEM_EXCEPTION(StackFaultException)
/**
 * Abort.
 */
DECLARE_SYSTEM_EXCEPTION(AbortException)
/**
 * 调试器异常.
 */
DECLARE_SYSTEM_EXCEPTION(DebugException)

} // namespace service
} // namespace kratos
